#include "PlayerObj.h"
#include "Environment.h"
#include "PublicMarcos.h"
#include "math.h"
#include "GameRoom.h"

PlayerObj::PlayerObj( hgeAnimation* player, hgeSprite* spr1, hgeSprite* spr2, hgeSprite* spr3, hgeSprite* shift, hgeSprite* PlayerMainBullet, hgeSprite* PlayerTraceBulletA ,hgeSprite* PlayerTraceBulletB,hgeSprite* PlayerTraceBulletC,hgeSprite* PlayerBoom,HEFFECT bulletEffect,HEFFECT boomEffect,HEFFECT shiftEffect,
hgeParticleSystem *part,float speed,float _x,float _y ) :
m_player(player),
m_spr1(spr1),
m_spr2(spr2),
m_spr3(spr3),
m_shift(shift),
m_PlayerMainBullet(PlayerMainBullet),
m_PlayerTraceBulletA(PlayerTraceBulletA),
m_PlayerTraceBulletB(PlayerTraceBulletB),
m_PlayerTraceBulletC(PlayerTraceBulletC),
m_PlayerBoom(PlayerBoom),
m_BulletEffect(bulletEffect),
m_BoomEffect(boomEffect),
m_shiftEffect(shiftEffect),
m_speed(speed),m_x(_x),m_y(_y),m_rad(0),m_r(48),m_isShift(false),m_booms(3),m_boomTime(0.0f)
,m_vx(0),m_vy(-_BULLET_CITY),m_life(_PLAYER_DEFAULT_LIFE),m_part(part)
{
	m_player->Play();
	m_PlayerMainBullet->SetDefaultRotation(-(float)_PI/2);
	m_part->info.fSpeedMax = 1000;
	m_part->info.fSpeedMin = 1000;
}

PlayerObj::~PlayerObj()
{
}

void PlayerObj::Update()
{
	float dt = Environment::GetDelta();
	m_rad+=dt*6;
	if (m_rad>=2*_PI) m_rad = 0;
	if (Environment::GetKey()==NULL) {
		noMove();
	}
	if (Environment::GetKeyState(HGEK_SHIFT)) {
		setShift();
	}
	else {
		unsetShift();
	}
	if (Environment::GetKeyState(HGEK_UP)) {
		MoveUp();
	}
	if (Environment::GetKeyState(HGEK_DOWN)) {
		MoveDown();
	}
	if (Environment::GetKeyState(HGEK_LEFT)) {
		MoveLeft();
	}
	if (Environment::GetKeyState(HGEK_RIGHT)) {
		MoveRight();
	}
	if (Environment::GetKeyState(HGEK_Z)) {
		ZFight();
	}
	if (Environment::GetKeyState(HGEK_X)) {
		XFight();
	}
	m_player->Update(dt);
	m_bulletMan.Update();
	m_part->MoveTo(m_x,m_y);
	m_part->Update(dt);
	if (fabs(m_boomTime-2.0f)<1e-2) {
		GameRoom::Boom();
	}
}

void PlayerObj::Render()
{
	m_part->Render();
	m_player->Render(m_x,m_y);
	m_bulletMan.Render();
	if (m_boomTime>0){
		BoomRender();
	}
	m_spr1->Render(m_x+m_r*cosf(m_rad),m_y+m_r*sinf(m_rad));
	m_spr2->Render(m_x+m_r*cosf(m_rad+(float)_PI/3*2),m_y+m_r*sinf(m_rad+(float)_PI/3*2));
	m_spr3->Render(m_x+m_r*cosf(m_rad+(float)_PI/3*4 ),m_y+m_r*sinf(m_rad+(float)_PI/3*4));
	if (m_isShift)
	{
		m_shift->RenderEx(m_x,m_y,m_rad,(m_r-23)/5);
		m_shift->RenderEx(m_x,m_y,-m_rad,(m_r-23)/5);
	}
	else {
		m_shift->RenderEx(m_x,m_y,m_rad,float(5/(m_r-23)-0.2) );
		m_shift->RenderEx(m_x,m_y,-m_rad,float(5/(m_r-23)-0.2) );
	}
}

void PlayerObj::MoveLeft()
{
	m_player->SetTextureRect(0,48,32,48);
	m_x -= m_speed*Environment::GetDelta();
	if (m_x<_GAMEROOM_L+16) m_x=_GAMEROOM_L+16;
	if (m_player->GetFrame()==7)
		m_player->SetFrame(4);
}

void PlayerObj::MoveRight()
{
	m_player->SetTextureRect(0,96,32,48); 
	m_x += m_speed*Environment::GetDelta();
	if (m_x>_GAMEROOM_R-16) m_x=_GAMEROOM_R-16;
	if (m_player->GetFrame()==7)
		m_player->SetFrame(4);
}

void PlayerObj::MoveUp()
{
	m_y-= m_speed*Environment::GetDelta();
	if (m_y<24) m_y=24;
}

void PlayerObj::MoveDown()
{
	m_y+=m_speed*Environment::GetDelta();
	if (m_y>_WINDOWS_HEIGHT-24) m_y=_WINDOWS_HEIGHT-24;
}

void PlayerObj::noMove()
{
	m_player->SetTextureRect(0,0,32,48);
}

hgeRect* PlayerObj::getCollision(hgeRect* rect)
{
	if (m_isShift)
	return m_player->GetBoundingBoxEx(m_x,m_y,0,0.0005f,0.00005f,rect);
	else 
	return m_player->GetBoundingBoxEx(m_x,m_y,0,0.005f,0.0005f,rect);
}

void PlayerObj::ZFight()
{
	static int num;
	num++;
	if (num%4==0) {
		Environment::Effect_PlayEx(m_BulletEffect,8);
		m_bulletMan.addBullet(new BulletInfo(m_PlayerMainBullet,m_x+8,m_y ,0,-_BULLET_CITY,0,0,0));
		m_bulletMan.addBullet(new BulletInfo(m_PlayerMainBullet,m_x-8,m_y,0,-_BULLET_CITY,0,0,0));
		m_bulletMan.addBullet(new BulletInfo(m_PlayerTraceBulletA,m_x+m_r*cosf(m_rad),m_y+m_r*sinf(m_rad),m_vx,m_vy,0,0,1));
		m_bulletMan.addBullet(new BulletInfo(m_PlayerTraceBulletB,m_x+m_r*cosf(m_rad+(float)_PI/3*2),m_y+m_r*sinf(m_rad+(float)_PI/3*2),m_vx,m_vy,0,0,1));
		m_bulletMan.addBullet(new BulletInfo(m_PlayerTraceBulletC,m_x+m_r*cosf(m_rad+(float)_PI/3*4),m_y+m_r*sinf(m_rad+(float)_PI/3*4),m_vx,m_vy,0,0,1));
		num = 0;
	}
}

void PlayerObj::XFight()
{
	if (m_booms>0 && fabs(m_boomTime)<1e-6) {
		m_booms--;
		m_boomTime = 3.0f;
		m_part->Fire();
		Environment::Effect_PlayEx(m_BoomEffect,80);
	}
}

void PlayerObj::setShift()
{
	if (!m_isShift) {
		m_speed*=float(2)/5;
		Environment::Effect_PlayEx(m_shiftEffect,20);
	}
	m_isShift = true;
	m_r-=Environment::GetDelta()*100;
	if (m_r<28) m_r = 28.0;
}

void PlayerObj::unsetShift()
{
	m_r+=Environment::GetDelta()*30;
	if (m_r>48.0) m_r = 48.0;
	if (m_isShift) m_speed*=float(5)/2;
	m_isShift = false;
}

int PlayerObj::checkCollision( hgeRect* rect )
{
	return (m_bulletMan.checkCollision(rect));
}

void PlayerObj::lockTarget( float x, float y )
{
	float r = sqrt(sqr(x - m_x) + sqr(y - m_y));
	m_vx = (x - m_x) / r * _BULLET_CITY;
	m_vy = (y - m_y) / r * _BULLET_CITY;
	m_bulletMan.LockTarget(x, y);
}

void PlayerObj::unlockTarget()
{
	m_vx = 0;
	m_vy = -_BULLET_CITY;
	m_bulletMan.unLockTarget();
}

void PlayerObj::MakeDmg( int dmg )
{
	if (m_life==1) GameRoom::setGameOver();
	if (dmg>0) {
		m_life--;
		GameRoom::Boom();
		//TODO(Death Effect)
		m_part->Fire();// should be death part
		m_boomTime = 3.0f;
		m_booms = 3;
		m_x = _def_startx;
		m_y = _def_starty;
	}
}

void PlayerObj::BoomRender()
{
	static int num;
	num++;
	if (num%10<5){
		m_PlayerBoom->Render(50,0);
	}
	m_boomTime-=Environment::GetDelta();
	if (fabs(m_boomTime)<1e-2)
		m_boomTime = 0;
}